package com.itgacl.magic4j.modules.api.h5;

import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.itgacl.magic4j.common.base.AppBaseController;

import com.itgacl.magic4j.libcommon.bean.R;
import com.itgacl.magic4j.libcommon.constant.Constants;
import com.itgacl.magic4j.libcommon.util.GUIDUtil;
import com.itgacl.magic4j.modules.alipay.config.AlipayConfig;
import com.itgacl.magic4j.modules.alipay.service.AlipayService;
import com.itgacl.magic4j.modules.mp.config.WxMpConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;

/**
 * @author 徐达沛
 * @version 1.0
 * @description: 针对H5应用通用验证的API
 * @date 2021/9/10 14:40
 */
@Api(tags = "H5应用的通用API")
@Slf4j
@Controller
@RequestMapping("/h5app/api")
public class H5AppAuthApiController extends AppBaseController {

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private AlipayConfig alipayConfig;

    @Autowired
    private WxMpConfig wxMpConfig;

    /**
     * H5应用用户授权登录
     * @param response
     * @param oAuth2Scope
     * @param scancodeClient
     * @param clientRedirectUrl
     */
    @ApiOperation("H5应用用户授权登录")
    @GetMapping("/oauthLogin")
    public void oauthLogin(HttpServletResponse response,String oAuth2Scope, String scancodeClient, String clientRedirectUrl) {
        String serverRedirectUrl = null;//服务端重定向地址
        try {
            if (StringUtils.isBlank(clientRedirectUrl)) {
                write(JSON.toJSONString(R.fail("客户端回调地址不能为空")), response);
                return;
            }
            if (StringUtils.isBlank(oAuth2Scope)) {
                write(JSON.toJSONString(R.fail("用户授权范围不能为空")), response);
                return;
            }
            if (StringUtils.isBlank(scancodeClient)) {
                write(JSON.toJSONString(R.fail("扫码客户端不能为空")), response);
                return;
            }
            String state = URLEncoder.encode(clientRedirectUrl, "utf-8");
            if (scancodeClient.equals(Constants.SCANCODE_CLIENT.WX)) {
                switch (oAuth2Scope) {
                    case Constants.WX_USER_AUTH_SCOPE.PRIVATEINFO:
                        serverRedirectUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(wxMpConfig.getUserInfoUrl(), WxConsts.OAuth2Scope.SNSAPI_PRIVATEINFO, state);
                        break;
                    case Constants.WX_USER_AUTH_SCOPE.USERINFO:
                        serverRedirectUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(wxMpConfig.getUserInfoUrl(), WxConsts.OAuth2Scope.SNSAPI_USERINFO, state);
                        break;
                    case Constants.WX_USER_AUTH_SCOPE.BASE:
                        serverRedirectUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(wxMpConfig.getUserOpenIdUrl(), WxConsts.OAuth2Scope.SNSAPI_BASE, state);
                        break;
                    default:
                        write(JSON.toJSONString(R.fail("微信用户授权范围传值不正确")), response);
                        return;
                }
                log.info("微信网页授权，获取code，redirectUrl = {}", serverRedirectUrl);
            } else { //支付宝
                if (Constants.ALIPAY_USER_AUTH_SCOPE.BASE.equals(oAuth2Scope)) {
                    serverRedirectUrl = alipayService.buildAuthorizationUrl(alipayConfig.getUserIdUrl(), Constants.ALIPAY_USER_AUTH_SCOPE.BASE, state);
                } else {
                    serverRedirectUrl = alipayService.buildAuthorizationUrl(alipayConfig.getUserInfoUrl(), Constants.ALIPAY_USER_AUTH_SCOPE.USER, state);
                }
                log.info("支付宝网页授权，获取code，redirectUrl = {}", serverRedirectUrl);
            }
            response.sendRedirect(serverRedirectUrl);
        } catch (Exception e) {
            log.error("网页授权转发异常，获取code，redirectUrl = {}", serverRedirectUrl);
        }
    }

    @ApiOperation("获取微信用户详细信息")
    @GetMapping("/wxUserInfo")
    public void wxUserInfo(HttpServletResponse response, @RequestParam("code") String code, @RequestParam("state") String clientRedirectUrl) {
        WxOAuth2AccessToken wxOAuth2AccessToken;
        WxOAuth2UserInfo wxOAuth2UserInfo;
        try {
            log.info("微信网页授权，获取用户信息，code = {}，returnUrl = {}", code, clientRedirectUrl);
            wxOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code);
            wxOAuth2UserInfo = wxMpService.getOAuth2Service().getUserInfo(wxOAuth2AccessToken, null);
            log.info("微信网页授权，获取用户信息，wxMpUser = {}", JSON.toJSONString(wxOAuth2UserInfo));
            //todo 处理业务逻辑
            String token = GUIDUtil.genRandomGUID(); //生成登录token
            String redirectUrl = clientRedirectUrl + "&token=" + token+"&thirdPartyUserId="+wxOAuth2AccessToken.getOpenId()+"&userFrom="+Constants.SCANCODE_CLIENT.WX;
            log.info("微信网页授权，获取用户信息，redirectUrl = {}", redirectUrl);
            response.sendRedirect(redirectUrl);
        }  catch (Exception e) {
            log.error("微信网页授权异常 {}", e.getMessage());
            write(JSON.toJSONString(R.fail("获取微信用户信息异常：" + e.getMessage())),response);
        }
    }

    @ApiOperation("获取微信用户openId")
    @GetMapping("/wxUserOpenId")
    public void wxUserOpenId(HttpServletResponse response, @RequestParam("code") String code, @RequestParam("state") String clientRedirectUrl) {
        WxOAuth2AccessToken wxOAuth2AccessToken;
        try {
            log.info("微信网页授权，获取微信用户openId，code = {}，clientRedirectUrl = {}", code, clientRedirectUrl);
            wxOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code);
            log.info("微信网页授权，获取微信accessToken，accessToken = {}", JSON.toJSONString(wxOAuth2AccessToken));
            //todo 处理业务逻辑
            String token = GUIDUtil.genRandomGUID();//生成登录token
            String redirectUrl = clientRedirectUrl + "&token=" + token+"&thirdPartyUserId="+wxOAuth2AccessToken.getOpenId()+"&userFrom="+Constants.SCANCODE_CLIENT.WX;
            log.info("微信网页授权，获取用户openId，redirectUrl = {}", redirectUrl);
            response.sendRedirect(redirectUrl);
        }  catch (Exception e) {
            log.error("微信网页授权异常 {}", e.getMessage());
            write(JSON.toJSONString(R.fail("获取微信用户信息异常：" + e.getMessage())),response);
        }
    }

    /**
     * 该接口需要将支付宝开放平台的网页应用提交审核发布上线后才能够正确拿到支付宝用户信息
     * @param response
     * @param authCode
     * @param clientRedirectUrl
     */
    @ApiOperation("获取支付宝开放平台用户信息")
    @GetMapping("/alipayUserInfo")
    public void alipayUserInfo(HttpServletResponse response, @RequestParam("auth_code") String authCode, @RequestParam("state") String clientRedirectUrl) {
        try {
            AlipaySystemOauthTokenResponse oauthToken = alipayService.getOauthToken(authCode);
            AlipayUserInfoShareResponse alipayUserInfo = alipayService.getAlipayUserInfo(oauthToken.getAccessToken());
            log.info("支付宝网页授权，获取用户信息，alipayUser = {}", JSON.toJSONString(alipayUserInfo));
            /**
             * 获取到的支付宝用户数据
             * {
             * 	"avatar": "https://tfs.alipayobjects.com/images/partner/TB1Nyhpck9iDuNjmgXdXXb.6VXa",
             * 	"body": "{\"alipay_user_info_share_response\":{\"code\":\"10000\",\"msg\":\"Success\",\"avatar\":\"https:\\/\\/tfs.alipayobjects.com\\/images\\/partner\\/TB1Nyhpck9iDuNjmgXdXXb.6VXa\",\"city\":\"广州市\",\"gender\":\"m\",\"nick_name\":\"孤傲苍狼\",\"province\":\"广东省\",\"user_id\":\"2088202818521984\"},\"sign\":\"MU3dO4SnayeDcUl+0gpE4DxYgjXV+kHKwI4wI7s1OpSPilU+43h8uIcq1w7WcSoinkx6EVA8l3O6Sho+KRkSxbXc4C+Y8I5foK3i67Pu1dj4qm4q3sBu37OVS9iHfg4cb8f65eFHE/ssoqt8d1AMbGj6duJ8uF0wVXvFD4yRFuqbtS7aXzxN4zynG/YgfZupXRi4S4929pU6ZUHDKp0MQa4m3njG+POXqRVnQ7olq9X7qhb74293k8zSWxO5sV3Xeb5A6hC79GqypaqLbyxKHbePyqYIYxdzh4c+iP2xDr+pouVUpWucBO4ZtK5wTiK76+/E5NSK0+g4KoTqipfNxw==\"}",
             * 	"city": "广州市",
             * 	"code": "10000",
             * 	"errorCode": "10000",
             * 	"gender": "m",
             * 	"msg": "Success",
             * 	"nickName": "孤傲苍狼",
             * 	"params": {},
             * 	"province": "广东省",
             * 	"success": true,
             * 	"userId": "2088202818521984"
             * }
             */
            //todo 处理业务逻辑
            String token = GUIDUtil.genRandomGUID();//生成登录token
            String redirectUrl = clientRedirectUrl + "&token=" + token+"&thirdPartyUserId="+oauthToken.getUserId()+"&userFrom="+Constants.SCANCODE_CLIENT.ALIPAY;
            log.info("支付宝网页授权，获取用户信息，redirectUrl = {}", redirectUrl);
            response.sendRedirect(redirectUrl);
        } catch (Exception e) {
            log.error("支付宝网页授权异常 {}", e.getMessage());
            write(JSON.toJSONString(R.fail("获取微信用户信息异常：" + e.getMessage())), response);
        }
    }

    @ApiOperation("获取支付宝开放平台用户ID")
    @GetMapping("/alipayUserId")
    public void alipayUserId(HttpServletResponse response, @RequestParam("auth_code") String authCode, @RequestParam("state") String clientRedirectUrl) {
        try {
            AlipaySystemOauthTokenResponse oauthToken = alipayService.getOauthToken(authCode);
            log.info("支付宝网页授权，获取AccessToken，oauthToken = {}", JSON.toJSONString(oauthToken));
            //todo 处理业务逻辑
            String token = GUIDUtil.genRandomGUID();//生成登录token
            String redirectUrl = clientRedirectUrl + "&token=" + token+"&thirdPartyUserId="+oauthToken.getUserId()+"&userFrom="+Constants.SCANCODE_CLIENT.ALIPAY;
            log.info("支付宝网页授权，获取用户Id，redirectUrl = {}", redirectUrl);
            response.sendRedirect(redirectUrl);
        } catch (Exception e) {
            log.error("支付宝网页授权异常 {}", e.getMessage());
            write(JSON.toJSONString(R.fail("获取微信用户信息异常：" + e.getMessage())), response);
        }
    }

}
